package Reproductor;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javazoom.jl.decoder.*;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;
import javazoom.jl.player.advanced.PlaybackEvent;
import javazoom.jl.player.advanced.PlaybackListener;

public class newAdvancedPlayer {
    
    private Bitstream bitstream;
    private Decoder decoder;
    private AudioDevice audio;
    private boolean closed = false;
    private boolean complete = false;
    private float lastFrame = 0;
    private int lastPosition = 0;
    private int lastMSPosition = 0;
    private newPlaybackListener listener;
    private float ms_per_frame;

    public newAdvancedPlayer(InputStream paramInputStream) throws JavaLayerException {
      this(paramInputStream, null);
    }

    public newAdvancedPlayer(InputStream paramInputStream, AudioDevice paramAudioDevice) throws JavaLayerException {
        this.bitstream = new Bitstream(paramInputStream);
        if (paramAudioDevice != null) {
              this.audio = paramAudioDevice;
        }
        else {
              this.audio = FactoryRegistry.systemRegistry().createAudioDevice();
        }
        this.audio.open(this.decoder = new Decoder());
    }

    public void play() throws JavaLayerException {
        play(2147483647);        
    }

    public boolean play(int paramInt)  throws JavaLayerException {
        boolean bool = true;        
        if (this.listener != null) {
            this.listener.playbackStarted(createEvent(PlaybackEvent.STARTED));            
        }
        while ((paramInt-- > 0) && (bool)) {
            bool = decodeFrame();
        }        
        AudioDevice localAudioDevice = this.audio;
        if (localAudioDevice != null) {
            localAudioDevice.flush();
            synchronized (this) {
                this.complete = (!this.closed);
                close();
            }
            if (this.listener != null) {
                this.listener.playbackFinished(createEvent(localAudioDevice, PlaybackEvent.STOPPED));
            }
        }        
        return bool;
    }

    public synchronized void close()  {
        AudioDevice localAudioDevice = this.audio;
        if (localAudioDevice != null) {
            this.closed = true;
            this.audio = null;
            localAudioDevice.close();
            this.lastPosition = localAudioDevice.getPosition();
            try {
              this.bitstream.close();
            }
            catch (BitstreamException localBitstreamException) {
            }
        }
    }

    protected boolean decodeFrame() throws JavaLayerException  {
        try {
            AudioDevice localAudioDevice = this.audio;
            if (localAudioDevice == null) {
                return false;
            }
            Header localHeader = this.bitstream.readFrame();
            if (localHeader == null) {
                return false;
            }
            SampleBuffer localSampleBuffer = (SampleBuffer)this.decoder.decodeFrame(localHeader, this.bitstream);
            synchronized (this) {
                localAudioDevice = this.audio;
                if (localAudioDevice != null) {
                    localAudioDevice.write(localSampleBuffer.getBuffer(), 0, localSampleBuffer.getBufferLength());
                }
            }
            this.bitstream.closeFrame();
        }
        catch (RuntimeException localRuntimeException) {
            throw new JavaLayerException("Exception decoding audio frame", localRuntimeException);
        }
        return true;
    }

    protected boolean skipFrame() throws JavaLayerException  {
        Header localHeader = this.bitstream.readFrame();
        if (localHeader == null) {
            return false;
        }
        this.bitstream.closeFrame();
        return true;
    }

    public boolean play(int paramInt1, int paramInt2) throws JavaLayerException {
        boolean bool = true;
        int i = paramInt1;
        while ((i-- > 0) && (bool)) {
            bool = skipFrame();
        }
        Header localHeader = this.bitstream.readFrame();
        ms_per_frame = localHeader.ms_per_frame();
        return play(paramInt2 - paramInt1);
    }

    private newPlaybackEvent createEvent(int paramInt) {
        return createEvent(this.audio, paramInt);
    }

    private newPlaybackEvent createEvent(AudioDevice paramAudioDevice, int paramInt)  {
        return new newPlaybackEvent(this, paramInt, paramAudioDevice.getPosition());
    }

    public void setPlayBackListener(newPlaybackListener paramPlaybackListener) {
        this.listener = paramPlaybackListener;
    }

    public newPlaybackListener getPlayBackListener() {
        return this.listener;
    }

    public void stop() {
        this.listener.playbackFinished(createEvent(newPlaybackEvent.STOPPED));
        close();
    }
    
    public float getFramePosition() throws BitstreamException{        
        AudioDevice localAudio = this.audio;
        int lastms = localAudio.getPosition();        
        float fxms = 1/ms_per_frame;        
        lastFrame = lastms*fxms;        
        return lastFrame;
    }
    
    public int getBitrate() {
        Header localHeader = null;
        try {
            localHeader = this.bitstream.readFrame();
        } catch (BitstreamException ex) {
            Logger.getLogger(newAdvancedPlayer.class.getName()).log(Level.SEVERE, null, ex);
        }
        return localHeader.bitrate();
    }
    
    public float getFramePerMilisecond() throws BitstreamException{ 
        float fxms = 1/ms_per_frame;
        return fxms;
    }
    
    
}
